/*******************************************************************************
 * This file is part of blueprint4j www.blueprint4j.org.
 * 
 *     blueprint4j is free software: you can redistribute it and/or modify
 *     it under the terms of the GNU Lesser General Public License as published by
 *     the Free Software Foundation, either version 3 of the License, or
 *     (at your option) any later version.
 * 
 *     blueprint4j is distributed in the hope that it will be useful,
 *     but WITHOUT ANY WARRANTY; without even the implied warranty of
 *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *     GNU Lesser General Public License for more details.
 * 
 *     You should have received a copy of the GNU Lesser General Public License
 *     along with blueprint4j. If not, see <http://www.gnu.org/licenses/>.
 ******************************************************************************/
/**
* $Log: Semaphore.java,v $
* Revision 1.2  2004/09/14 13:54:24  travisb
* New Log system brought in
*
* Revision 1.1.1.1  2004/04/22 12:56:16  travisb
* Fir
*
* Revision 1.1.1.1  2003/12/21 09:04:12  jaspervdb
* no message
*
* Revision 1.1.1.1  2003/10/20 15:31:28  travisb
* First import into CVS at Cellstop
*
* Revision 1.2  2003/03/30 15:41:56  jasper
* Migration
*
* Revision 1.2  2003/01/12 13:39:17  jasper
* Changed Binder to GUI level
*
* Revision 1.3  2002/12/17 18:39:55  travis
* Changed Thread Logs and Settings classes removed Dead Weight
*
* Revision 1.1.1.1  2002/12/16 22:14:01  jasper
* no message
*
* This class lets only the same names enter a semaphore room
*/

package blueprint4j.utils;

import java.util.*;

public class Semaphore {
	//private static String occupied = null;
	//private static long entry_time = 0;
	private static String current_group = null;
	private static List<String> current_methods = null;
	private static Hashtable groups = new Hashtable();

	/**
	 * Only one group at a time can execute, no duplicate methods in a executing group may execute
	 */
	public static void addGroup(String group,String method) {
		if (groups.containsKey(group)) {
			List<String> methods = (List<String>) groups.get(group);
			if (!methods.contains(method)) {
				methods.add(method);
			}
		} else {
			List<String> methods = new ArrayList<String>();
			methods.add(method);
			groups.put(group,methods);
		}
	}

	public static String getCurrentOwner() {
		if (current_group != null) {
			return current_group + "[" + current_methods.toString() + "]";
		} else {
			return "None";
		}
	}

	/**
	 * Only allows a new or a specific type to enter
	 */
	public static boolean enter(String group,String method) {
		// the group that wishes to enter must be registered
		if (!groups.containsKey(group)) {
			Log.debug.out("Error occurred while trying to enter Semaphore State","Groups that wants to enter the semaphore state must be registered. (addGroup) ["+group+"] is not registered");
			return false;
		}
		// make sure that method in group is registered
		List<String> methods = (List<String>) groups.get(group);
		if (!methods.contains(method)) {
			Log.debug.out("Error occurred while trying to enter Semaphore State","Method that wants to enter the semaphore state must be registered. (addGroup) ["+method+"] is not registered");
			return false;
		}
		// Check if group is null (vacant), then enter
		if (current_group == null ) {
			current_group = group;
			current_methods = new ArrayList<String>();
			current_methods.add(method);
			return true;
		}
		// if the entering group is the current group, then check that method doesn't already exist
		if (current_group.equals(group)) {
			// is the method already in the semaphore room
			if (!current_methods.contains(method)) {
				current_methods.add(method);
				return true;
			}
			return false;
		}
		return false;
	}

	/**
	 * Exits the type only if entered
	 */
	public static void exit(String group,String method) {
		if (current_group == null || !current_group.equals(group)) {
			return;
		}
		if (current_methods.contains(method)) {
			current_methods.remove(method);
			if (current_methods.size() == 0) {
				current_group = null;
			}
		}
	}

	public static long getEntryTime() {
		return 0;
	}
}
